package com.example.universitylibraryback.pipeline;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Pipeline<T> {
    private final List<Filter<T>> filters = new ArrayList<>();
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private BlockingQueue<T> inputQueue;

    public Pipeline() {
        this.inputQueue = new LinkedBlockingQueue<>();
    }

    public Pipeline<T> addFilter(Filter<T> filter) {
        BlockingQueue<T> outputQueue = new LinkedBlockingQueue<>();
        final BlockingQueue<T> currentInput = inputQueue;
        executorService.submit(() -> {
            try {
                filter.process(currentInput, outputQueue);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        inputQueue = outputQueue;
        filters.add(filter);
        return this;
    }

    public void submit(T data) {
        inputQueue.offer(data);
    }

    public void shutdown() {
        executorService.shutdown();
    }
}